<?php
/**
 * Created by PhpStorm.
 * User: 王松
 * Time: 2017/6/21 13:34
 */

namespace App\Transformers;

use App\Models\MedicalDispose;
use App\Models\MedicalHpiSub;
use App\Models\MedicalRecord;
use App\Models\PastHistory;
use http\Exception\InvalidArgumentException;
use League\Fractal\ParamBag;
use League\Fractal\TransformerAbstract;

class DrugsOfRecordTransformer extends TransformerAbstract
{
    protected $availableIncludes = ['hpiSub', 'past', 'dispose', 'previousDispose'];

    protected $record_id;

    protected $patient_id;

    protected $columns;

    /**
     * 处理model
     * @var \App\Models\MedicalDispose
     */
    protected $dispose;

    public function __construct($record_id = null, $patient_id = null)
    {
        $this->record_id  = $record_id;
        $this->patient_id = $patient_id;

        $this->dispose = new MedicalDispose();

        if (\Auth::user()->hospital->isWestern()) {
            $this->columns = ['medication'];
        } else {
            $this->columns = ['medication', 'cn_medication'];
        }
    }

    public function transform(array $array)
    {
        return $array;
    }

    /**
     * 返回 现病史用药
     * @param                          $array
     * @param \League\Fractal\ParamBag $bag
     * @return \League\Fractal\Resource\NullResource|\League\Fractal\Resource\Primitive
     */
    public function includeHpiSub($array, ParamBag $bag)
    {
        if (empty($this->record_id)) {
            throw new InvalidArgumentException('缺少病历ID', 422);
        }

        $medication = MedicalHpiSub::where(['record_id' => $this->record_id])->get(['id','medication', 'cn_medication']);

        if (is_null($medication))
            return $this->null();

        $data = [];

        foreach ($this->columns as $column) {
            $data[$column] = $medication->pluck($column)
                                        ->reject(function ($item) {
                                            return empty($item);
                                        })
                                        ->flatten(1)->toArray();
        }

        return $this->primitive($data);
    }

    /**
     * 返回 既往史用药
     * @param                          $array
     * @param \League\Fractal\ParamBag $bag
     * @return \League\Fractal\Resource\Item|\League\Fractal\Resource\NullResource
     */
    public function includePast($array, ParamBag $bag)
    {
        if (empty($this->record_id)) {
            throw new InvalidArgumentException('缺少病历ID', 422);
        }

        $result = PastHistory::where(['record_id' => $this->record_id])->first(['medication']);

        if (is_null($result)) {
            return $this->null();
        }

        $array = (array)(empty($result->medication) ? [] : $result->medication);

        return $this->item($array, function ($array) {
            return $array;
        });
    }

    /**
     * 返回 上次病历 处理用药
     * @param                          $array
     * @param \League\Fractal\ParamBag $bag
     * @return \League\Fractal\Resource\NullResource|\League\Fractal\Resource\Primitive
     */
    public function includePreviousDispose($array, ParamBag $bag)
    {
        $record = new MedicalRecord();

        if (empty($this->record_id)) {
            $previous = $record->previousWithPatient($this->patient_id)->first(['id']);
        } else {
            try {
                $previous = $record->previous($this->record_id);
            } catch (\InvalidArgumentException $e) {
                $previous = null;
            }
        }

        if (!is_null($previous)) {
            $medication = $this->dispose->whereRecordId($previous->id)
                                        ->select($this->columns)->first();
            if (is_null($medication)) {
                return $this->null();
            } else {
                return $this->primitive($medication->toArray());
            }
        }

        return $this->null();
    }

    /**
     * 返回 处理用药 default参数携带的是默认值，当处理查询不到用药时，返回默认值里的用药
     * @param                          $array
     * @param \League\Fractal\ParamBag $bag
     * @return \League\Fractal\Resource\Primitive
     */
    public function includeDispose($array, ParamBag $bag)
    {
        $medication = null;

        if ($this->record_id) {
            $medication = $this->dispose->whereRecordId($this->record_id)
                                        ->select($this->columns)->first();
        }
        $columns = [];

        if (!is_null($medication)) {

            foreach ($this->columns as $column) {
                /** @var MedicalDispose $medication */
                if (!$medication->$column) {
                    $columns[] = $column;
                }
            }
        } else {
            $columns = ['medication', 'cn_medication'];
        }

        $defaults = $bag->get('default');
        $data = [];
        if (!is_null($medication)) {
            if (is_null($defaults) || !$columns) {
                return $this->primitive($medication->toArray());
            } else {
                $data = $medication->toArray();
            }
        }

        $this->columns = $columns;

        foreach ($this->columns as $column) {
            $data[$column] = [];
        }

        $defaults = array_diff($defaults, $this->currentScope->getManager()->getRequestedIncludes());
        $defaults = array_intersect($defaults, $this->availableIncludes);

        foreach ($defaults as $default) {
            $method = 'include' . ucfirst($default);

            if (method_exists($this, $method)) {
                $include = $this->$method($array, $bag)->getData();
                if (is_array($include)) {
                    foreach ($this->columns as $column) {
                        if (array_key_exists($column, $include)) {
                            $data[$column] = array_merge($data[$column], (array)$include[$column]);
                        }
                    }
                }
            }
        }

        return $this->primitive($data);
    }
}